package com.aek.ebey.sys.web.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.aek.common.core.Result;
import com.aek.common.core.base.BaseController;
import com.aek.ebey.sys.core.BeanMapper;
import com.aek.ebey.sys.core.jackson.annotation.AllowProperty;
import com.aek.ebey.sys.core.jackson.annotation.IgnoreProperties;
import com.aek.ebey.sys.enums.TenantType;
import com.aek.ebey.sys.model.SysTenant;
import com.aek.ebey.sys.model.SysUser;
import com.aek.ebey.sys.model.custom.HplTenant;
import com.aek.ebey.sys.model.custom.SuperviseTenant;
import com.aek.ebey.sys.model.query.TenantQuery;
import com.aek.ebey.sys.model.vo.SysTenantAdminVo;
import com.aek.ebey.sys.model.vo.SysTenantUserVo;
import com.aek.ebey.sys.service.SysTenantService;
import com.aek.ebey.sys.service.SysUserService;
import com.aek.ebey.sys.web.request.HplTenantRequest;
import com.aek.ebey.sys.web.request.TenantRequest;
import com.aek.ebey.sys.web.validator.group.Add;
import com.aek.ebey.sys.web.validator.group.Edit;
import com.baomidou.mybatisplus.plugins.Page;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;

/**
 * <p>
 * 机构 前端控制器
 * </p>
 *
 * @author aek
 * @since 2017-05-06
 */
@RestController
@RequestMapping("/sys/tenant")
@Api(value = "SysTenantController", description = "租户管理")
public class SysTenantController extends BaseController {

	@Autowired
	private SysTenantService tenantService;
	@Autowired
	private SysUserService userService;

	/**
	 * 创建子机构
	 * 
	 * @param request
	 *            子机构信息(包含管理员信息)
	 * @return
	 */
	@PreAuthorize("hasAuthority('SYS_TENANT_NEW')")
	@PostMapping(value = "/")
	@ApiOperation(value = "创建机构", httpMethod = "POST", produces = "application/json")
	@ApiResponse(code = 0, message = "OK", response = Result.class)
	public Result<SysTenant> createSubTenant(@Validated(value = Add.class) @RequestBody TenantRequest request) {
		SysUser admin = null;
		SysTenant tenant = null;

		if (request.getCreateAdmin()) {
			admin = new SysUser(request.getRealName(), request.getPassword(), request.getMobile(), request.getEmail());
		}

		tenant = BeanMapper.map(request, SysTenant.class);
		this.disposeCustomData(request, tenant);
		this.tenantService.createSubTenant(tenant, admin);
		return response(tenant);
	}

	/**
	 * 不同类型租户字段不同处理
	 * 
	 * @param request
	 *            请求租户属性
	 * @param tenant
	 *            数据库租户属性
	 */
	private void disposeCustomData(TenantRequest request, SysTenant tenant) {
		Integer tenantType = request.getTenantType();
		// 判断机构类型
		if (TenantType.HOSPITAL.getNumber().equals(tenantType)) {
			HplTenant hplTenant = new HplTenant();
			HplTenantRequest hplTenantRequest = request.getHplTenant();
			hplTenant.setCategory(hplTenantRequest.getCategory());
			hplTenant.setEconomicType(hplTenantRequest.getEconomicType());
			hplTenant.setGrade(hplTenantRequest.getCategory());
			hplTenant.setHierarchy(hplTenantRequest.getEconomicType());
			hplTenant.setManageType(hplTenantRequest.getManageType());
			tenant.setHplTenant(hplTenant);
		}
		if (TenantType.SUPERVISE.getNumber().equals(tenantType)) {
			// 监管机构字段处理
			SuperviseTenant superviseTenant = new SuperviseTenant();
			tenant.setSuperviseTenant(superviseTenant);
		}
	}

	/**
	 * 修改机构信息
	 * 
	 * @param request
	 * @return
	 */
	@PreAuthorize("hasAuthority('SYS_TENANT_MANAGE')")
	@PutMapping(value = "/edit")
	@ApiOperation(value = "编辑机构信息", httpMethod = "PUT", produces = "application/json")
	@ApiResponse(code = 0, message = "OK", response = Result.class)
	public Result<SysTenant> editTenant(@Validated(value = Edit.class) @RequestBody TenantRequest request) {
		SysTenant tenant = null;
		SysUser admin = null;

		if (request.getCreateAdmin()) {
			admin = new SysUser(request.getRealName(), request.getPassword(), request.getMobile(), request.getEmail());
		}

		tenant = BeanMapper.map(request, SysTenant.class);
		this.tenantService.modifySubTenant(tenant, admin);
		return response(tenant);
	}

	/**
	 * 根据ID查询机构信息
	 *
	 * @return
	 */
	@PreAuthorize("hasAnyAuthority('SYS_TENANT_DETAILED_VIEW','SYS_TENANT_MANAGE')")
	@GetMapping(value = "/view/{tenantId}")
	@ApiOperation(value = "根据ID查询机构信息", httpMethod = "GET", produces = "application/json")
	@ApiResponse(code = 0, message = "OK", response = Result.class)
	@ApiImplicitParam(name = "tenantId", value = "机构ID", paramType = "path", required = true)
	public Result<SysTenantUserVo> queryTenant(@PathVariable("tenantId") Long tenantId) {
		SysTenant tenant = this.tenantService.selectById(tenantId);
		SysTenantUserVo tvo = new SysTenantUserVo();
		tvo.setTenant(tenant);
		SysUser createUser = this.userService.selectById(tenant.getCreateBy());
		if (createUser != null) {
			tvo.setCreateName(createUser.getRealName());
		}
		if (tenant != null) {
			if (tenant.getAdminId() != null) {
				SysUser admin = this.userService.selectById(tenant.getAdminId());
				SysTenantAdminVo tAdmin = new SysTenantAdminVo();
				tAdmin.setRealName(admin.getRealName());
				tAdmin.setMobile(admin.getMobile());
				tAdmin.setEmail(admin.getEmail());
				tvo.setTenantAdmin(tAdmin);
			}
		}
		return response(tvo);
	}

	/**
	 * 查询机构管理首页列表
	 *
	 * @return
	 */
	@PreAuthorize("hasAuthority('SYS_TENANT_LIST_VIEW')")
	@IgnoreProperties(allow = { @AllowProperty(pojo = SysTenant.class, name = { "id", "name", "tenantType",
			"commercialUse", "province", "city", "county", "trial", "origin", "auditStatus", "subTenantLimit",
			"subTenant", "expireTime", "createTime", "enable" }) })
	@GetMapping(value = "/index/list")
	@ApiOperation(value = "分页查询子机构列表", httpMethod = "GET", produces = "application/json")
	@ApiImplicitParams({ @ApiImplicitParam(name = "pageNo", value = "起始页 [默认1]", paramType = "query", required = false),
			@ApiImplicitParam(name = "pageSize", value = "分页大小[默认10]", paramType = "query", required = false),
			@ApiImplicitParam(name = "tenantId", value = "租户ID [必须]", paramType = "query", required = true),
			@ApiImplicitParam(name = "enable", value = "启用未启用[true=启用,false=未启用]", paramType = "query", required = false),
			@ApiImplicitParam(name = "origin", value = "来源[1后台创建，2前台注册]", paramType = "query", required = false),
			@ApiImplicitParam(name = "auditStatus", value = "审核状态[1待审核,2自动通过,3人工通过,4已拒绝]", paramType = "query", required = false),
			@ApiImplicitParam(name = "tenantType", value = "机构类型[1=医疗机构,2=监管机构,3=设备供应商,4=设备维修商,5=配件供应商]", paramType = "query", required = false),
			@ApiImplicitParam(name = "commercialUse", value = "账户类型[0=试用,1=正式]", paramType = "query", required = false),
			@ApiImplicitParam(name = "trial", value = "是否测试[1 否, 0 是]", paramType = "query", required = false),
			@ApiImplicitParam(name = "keyword", value = "关键字", paramType = "query", required = false) })
	@ApiResponse(code = 200, message = "OK", response = Result.class)
	public Result<Page<SysTenant>> findPageByKeyword(TenantQuery query) {
		return response(this.tenantService.findPageByKeyword(query));
	}

	/**
	 * 停用机构
	 *
	 * @return
	 */
	@PreAuthorize("hasAuthority('SYS_TENANT_MANAGE')")
	@PostMapping(value = "/stop/{tenantId}")
	@ApiOperation(value = "停用机构", httpMethod = "POST", produces = "application/json")
	@ApiResponse(code = 200, message = "OK", response = Result.class)
	@ApiImplicitParam(name = "tenantId", value = "机构ID", paramType = "path", required = true)
	public Result<Object> stopTenant(@PathVariable(value = "tenantId", required = true) Long tenantId) {
		this.tenantService.stopTenantById(tenantId);
		return response();
	}

	/**
	 * 恢复机构
	 *
	 * @return
	 */
	@PreAuthorize("hasAuthority('SYS_TENANT_MANAGE')")
	@PostMapping(value = "/recover/{tenantId}")
	@ApiOperation(value = "恢复机构", httpMethod = "POST", produces = "application/json")
	@ApiResponse(code = 200, message = "OK", response = Result.class)
	@ApiImplicitParam(name = "tenantId", value = "机构ID", paramType = "path", required = true)
	public Result<Object> recoverTenant(@PathVariable(value = "tenantId", required = true) Long tenantId) {
		this.tenantService.recoverTenantById(tenantId);
		return response();
	}

	/**
	 * 删除机构
	 *
	 * @return
	 */
	@PreAuthorize("hasAuthority('SYS_TENANT_MANAGE')")
	@RequestMapping(value = "/delete/{tenantId}")
	@ApiOperation(value = "删除机构", httpMethod = "DELETE", produces = "application/json")
	@ApiResponse(code = 200, message = "OK", response = Result.class)
	@ApiImplicitParam(name = "tenantId", value = "机构ID", paramType = "path", required = true)
	public Result<Object> deleteTenant(@PathVariable(value = "tenantId", required = true) Long tenantId) {
		this.tenantService.deleteTenantById(tenantId);
		return response();
	}

	@PreAuthorize("hasAuthority('SYS_TENANT_MANAGE')")
	@RequestMapping(value = "/delay/tenant/{tenantId}")
	@ApiOperation(value = "机构延期", httpMethod = "DELETE", produces = "application/json")
	@ApiImplicitParams(value = {
			@ApiImplicitParam(name = "tenantId", value = "机构ID", paramType = "path", required = true),
			@ApiImplicitParam(name = "days", value = "时间(天)", paramType = "query", required = true),
			@ApiImplicitParam(name = "updateBy", value = "修改人ID", paramType = "query", required = true) })
	@ApiResponse(code = 200, message = "OK", response = Result.class)
	public Result<Object> delayTenant(@PathVariable(value = "tenantId", required = true) Long tenantId,
			@RequestParam(value = "days", required = true) Integer days,
			@RequestParam(value = "updateBy", required = true) Long updateBy) {
		this.tenantService.delayTenant(updateBy, tenantId, days);
		return response();
	}

}
